package com.ys.utils.mobao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ys.base.BaseParam;
import com.ys.utils.base.j2se.*;
import com.ys.utils.redis.Redis;
import com.ys.utils.spring.config.SystemError;
import com.ys.web.mobao.model.po.BindCard;
import com.ys.web.mobao.model.po.MobaoRechargeCreate;
import com.ys.web.mobao.model.po.MobaoWithholdingCreate;
import com.ys.web.pay.model.PayOrder;
import com.ys.web.pay.model.WithdrawRecordWait;
import com.ys.web.pay.model.vo.UserBank;
import com.ys.web.user.login.LoginInfo;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class MobaoPay {
    public static Map<String,Object> bindCardBin(BindCard bindCard){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUERY_CARD_BIN");
        paramsMap.put("apiVersion", "1.0.0.0");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("spCardNo", bindCard.getCardNo());
        String sourceData = null;
        try {
            sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400",jsonObject.getString("retMsg"));
            }
//            System.err.println(responseMsg);
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg).getInnerMap();
        } catch (Exception e) {
            Logger.error("查询bin操作失败",e);
            SystemError.wrapBs("400", "查询bin操作失败");
            return null;
        }
    }
    public static String bindCard(BindCard bindCard){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUICK_SIGN");
        paramsMap.put("apiVersion", "1.0.0.0");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("spCardNo", bindCard.getCardNo());
        paramsMap.put("spName", bindCard.getUserName());
        paramsMap.put("spTel", bindCard.getMobile());
        paramsMap.put("spCardId", bindCard.getIdCardNum());
        paramsMap.put("merchTradeNo", BaseParam.getOrderSN());
        paramsMap.put("merchUrl", bindCard.getNotifyUrl());
        paramsMap.put("payType", "131");
        String sourceData = null;
        try {
            sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            return Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
        } catch (Exception e) {
            Logger.error("绑卡操作失败",e);
            SystemError.wrapBs("400", "绑卡操作失败");
            return sourceData;
        }
    }

    public static String bindCardQuery(LoginInfo loginInfo,BindCard bindCard){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUICK_SIGN");
        paramsMap.put("apiVersion", "1.0.0.0");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("spCardNo", bindCard.getCardNo());
        paramsMap.put("spName", loginInfo.getRealName());
        paramsMap.put("spTel", loginInfo.getPhone());
        paramsMap.put("spCardId", loginInfo.getRealIdCard());
        paramsMap.put("merchTradeNo", BaseParam.getOrderSN());
        paramsMap.put("merchUrl", bindCard.getNotifyUrl());
        paramsMap.put("payType", "131");
        String sourceData = null;
        try {
            sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            return Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
        } catch (Exception e) {
            SystemError.wrapBs("400", "操作失败");
            return sourceData;
        }
    }

    /**
     * mobao在线支付
     * @return
     */
    public static Map<String,Object> payInit(String signNo,String ip, MobaoRechargeCreate rechargeCreate){
        String responseMsg = "";
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","QUICK_SMS");
            paramsMap.put("apiVersion","1.0.0.0");
            paramsMap.put("custNo", Mobo360Config._merchantId);
            paramsMap.put("signNo",signNo);
            paramsMap.put("merchTradeNo", rechargeCreate.getRequestId());
            paramsMap.put("tradeAmt", StringHandler.fenToYuan(rechargeCreate.getAmount()));
            paramsMap.put("goodsName",rechargeCreate.getGoodsName());
            paramsMap.put("goodsDesc",rechargeCreate.getGoodsName());
            paramsMap.put("tradeTime", DateUtil.getDate(new Date(),"yyyyMMddHHmmss"));
            paramsMap.put("merchUrl",rechargeCreate.getNotifyUrl());
            paramsMap.put("merchParam", parseMerchParam(rechargeCreate));
            paramsMap.put("payEnvType",1);
            paramsMap.put("terminalType",1);
            paramsMap.put("tradeSummer",rechargeCreate.getGoodsName());
            paramsMap.put("manualOverTime",120);
            paramsMap.put("terminalId",ip);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);

            responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","发起支付失败");
            }
//            System.err.println(responseMsg);
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg).getInnerMap();
        }catch (Exception e){
            Logger.error("发起支付失败",e);
            SystemError.wrapBs("400","发起支付失败.");
        }
        return null;
    }

    public static String payment(String orderNo,String code,String smsId){
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","QUICK_PAYMENT");
            paramsMap.put("apiVersion","1.0.0.0");
            paramsMap.put("custNo",Mobo360Config._merchantId);
            paramsMap.put("orderNo",orderNo);
            paramsMap.put("validateCode", code);
            paramsMap.put("smsId",smsId);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);

            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
//            System.err.println(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","支付失败");
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg).getString("orderStatus");
        }catch (Exception e){
            Logger.error("支付确认失败",e);
            SystemError.wrapBs("400","支付确认失败.");
        }
        return null;
    }

    /**
     *
     * @param ip
     * @param rechargeCreate
     * @return 支付公司返回信息{"retCode": "1","serName": "XXXX","retMsg": "success","retData": {"orderNo": "112120191115001292","orderStatus": "00","consumerNo": "21323231432323122","codeUrl": "aHR0cHM6Ly9xci5hbGlwYXkuY29tL2JheDA1OTcwbmtuZnRhMmVibXZ4MDBhMw==","prepayNo": "500612774784724992"}}
     */
    public static Map<String,Object> alipay(String ip, MobaoRechargeCreate rechargeCreate){
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","ALIPAY");
            paramsMap.put("custNo",Mobo360Config._merchantId);
            paramsMap.put("merchTradeNo", rechargeCreate.getRequestId());
            paramsMap.put("tradeAmt",StringHandler.fenToYuan(rechargeCreate.getAmount()));
            paramsMap.put("goodsName",rechargeCreate.getBusinessType()==1?"商品":rechargeCreate.getGoodsName());
            paramsMap.put("goodsDesc",rechargeCreate.getBusinessType()==1?"商品":rechargeCreate.getGoodsName());
            paramsMap.put("tradeTime", DateUtil.getDate(new Date(),"yyyyMMddHHmmss"));
            paramsMap.put("merchUrl",rechargeCreate.getNotifyUrl());
            paramsMap.put("payEnvType",1);
            paramsMap.put("payType",172);
            paramsMap.put("merchParam",parseMerchParam(rechargeCreate));
            paramsMap.put("tradeSummer",rechargeCreate.getBusinessType()==1?"商品":rechargeCreate.getGoodsName());
            paramsMap.put("product",170);
            paramsMap.put("terminalType",1);
            paramsMap.put("terminalId",ip);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);
            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
//            System.err.println(responseMsg);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","发起支付失败");
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg).getInnerMap();
//            return new String(new Base64().decode(JSON.parseObject(responseMsg).getString("codeUrl")), "UTF-8");
        }catch (Exception e){
            Logger.error("支付宝支付失败",e);
            SystemError.wrapBs("500","支付宝支付失败");
        }
        return null;
    }

    private static String parseMerchParam(MobaoRechargeCreate rechargeCreate){
        return JSON.toJSONString(MapHandler.initMap("bt", StringHandler.getString(rechargeCreate.getBusinessType()),"orderId",rechargeCreate.getOrderId()));
    }

    public static JSONObject tradeStatusQuery(String orderNo){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUERY_TRADE_STATUS");
        paramsMap.put("apiVersion","1.0.0.0");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("merchTradeNo", orderNo);
        try {
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                //订单失效查不到订单信息
                if(jsonObject.getString("retMsg").contains("订单信息")){
                    jsonObject.put("orderStatus","-1");
                    return jsonObject;
                }
                Logger.error(responseMsg);
                SystemError.wrapBs("400","发起支付订单查询失败");
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg);
        } catch (Exception e) {
            Logger.error("发起支付订单查询操作失败",e);
            SystemError.wrapBs("400", "发起支付订单查询操作失败");
            return null;
        }
    }

    public static String balanceQuery(){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUERY_BALANCE");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("ccy", "CNY");
        String sourceData = null;
        try {
            sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","余额查询失败");
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg).getString("usableAmt");
        } catch (Exception e) {
            Logger.error("余额查询操作失败",e);
            SystemError.wrapBs("400", "余额查询操作失败");
            return sourceData;
        }
    }

    /**
     *
     * @param ip
     * @param payOrder
     * @return 支付公司返回信息    {"retCode": "1","seriesNo": null,"serName": "CAS","retMsg": "success","retData": {"orderRefundNo": "111120190918000007","orderNo": "111120190918000426","orderStatus": "00","tradeAmt": "0.01"}}
     * #退款
     */
    public static JSONObject refund(String ip, PayOrder payOrder){
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","REFUND");
            paramsMap.put("custNo",Mobo360Config._merchantId);
            paramsMap.put("merchTradeNo", payOrder.getOrderNo());
            paramsMap.put("orderNo", payOrder.getSerialNumber());
            paramsMap.put("tradeAmt",StringHandler.fenToYuan(StringHandler.getString(payOrder.getAmount())));
            paramsMap.put("terminalId",ip);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);
            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error("发起退款失败:"+jsonObject.getString("retMsg"));
                SystemError.wrapBs("400",jsonObject.getString("retMsg"));
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg);
        }catch (Exception e){
            Logger.error("发起退款失败",e);
            SystemError.wrapBs("500",e.getMessage());
        }
        return null;
    }

    public static JSONObject withdraw(String ip, String key, MobaoWithholdingCreate withholdingCreate, UserBank userBank){
        String responseMsg = "";
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","FUND_OUT");
            paramsMap.put("custNo", Mobo360Config._merchantId);
            paramsMap.put("merchTradeNo", withholdingCreate.getRequestId());
            paramsMap.put("accInType","2");
            paramsMap.put("accInNo",userBank.getCardNo());
            paramsMap.put("accInName", userBank.getUserName());
            paramsMap.put("tradeAmt", StringHandler.fenToYuan(withholdingCreate.getArrivalAmount()));
            paramsMap.put("tradeSummer", "货款");
            paramsMap.put("merchUrl",withholdingCreate.getNotifyUrl());
            paramsMap.put("payType",314);
            paramsMap.put("terminalType",1);
            paramsMap.put("terminalId",ip);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);

            responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
//            System.err.println(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","发起提现失败");
            }
            Redis.key.increment(key);
            Redis.key.setKeyTimeout(key, 86400L);
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg);
        }catch (Exception e){
            Logger.error("发起提现操作失败",e);
            SystemError.wrapBs("400","发起提现操作失败.");
        }
        return null;
    }
    public static JSONObject withdraw(String ip, String key, WithdrawRecordWait record){
        String responseMsg = "";
        try{
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("apiName","FUND_OUT");
            paramsMap.put("custNo", Mobo360Config._merchantId);
            paramsMap.put("merchTradeNo", record.orderNo);
            paramsMap.put("accInType","2");
            paramsMap.put("accInNo",record.getCardNo());
            paramsMap.put("accInName", record.getUserName());
            paramsMap.put("tradeAmt", StringHandler.fenToYuan(record.getWithdrawAmount()+""));
            paramsMap.put("tradeSummer", "货款");
            paramsMap.put("merchUrl",Mobo360Config._notifyUrl+"/onlinePay/transferDomestic/single/order/task/send");
            paramsMap.put("payType",314);
            paramsMap.put("terminalType",1);
            paramsMap.put("terminalId",ip);
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg",signMsg);
            log.info("mobaoPay---提现转账---"+Mobo360SignUtil.coverMap2String(paramsMap));
            responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            log.info("mobaoPay---提现转账返回参数---"+responseMsg);
//            System.err.println(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                Logger.error(responseMsg);
                SystemError.wrapBs("400","发起提现失败");
            }
            Redis.key.increment(key);
            Redis.key.setKeyTimeout(key, 86400L);
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg);
        }catch (Exception e){
            Logger.error("发起提现操作失败",e);
            SystemError.wrapBs("400","发起提现操作失败.");
        }
        return null;
    }

    public static JSONObject fundoutQuery(String orderNo){
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("apiName", "QUERY_FUNDOUT_STATUS");
        paramsMap.put("apiVersion","1.0.0.0");
        paramsMap.put("custNo", Mobo360Config._merchantId);
        paramsMap.put("merchTradeNo", orderNo);
        try {
            String sourceData = Mobo360SignUtil.coverMap2String(paramsMap);
            String signMsg = Mobo360SignUtil.signData(sourceData);
            paramsMap.put("signMsg", signMsg);

            String responseMsg = Mobo360Merchant.transact(Mobo360SignUtil.coverMap2String(paramsMap), Mobo360Config.MOBAOPAY_GETWAY);
            JSONObject jsonObject = JSON.parseObject(responseMsg);
            if(!jsonObject.getString("retMsg").equals("success") && !jsonObject.getString("retMsg").equals("成功")){
                //订单失效查不到订单信息
                if(jsonObject.getString("retMsg").contains("订单信息")){
                    jsonObject.put("orderStatus","-1");
                    return jsonObject;
                }
                SystemError.wrapBs("400","发起提现订单查询失败");
            }
            responseMsg = jsonObject.getString("retData");
            return JSON.parseObject(responseMsg);
        } catch (Exception e) {
            Logger.error("发起提现订单查询操作失败",e);
            SystemError.wrapBs("400", "发起提现订单查询操作失败");
            return null;
        }
    }
}
